package com.apes.fn.server.reworkAppraisal.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.fn.server.reworkAppraisal.model.ReworkAppraisal;
import com.apes.fn.server.reworkAppraisal.model.ReworkAppraisalItem;
import com.apes.fn.server.reworkAppraisal.repository.ReworkAppraisalRepository;
import com.apes.fn.server.reworkAppraisal.repository.ReworkAppraisalToSql;
import com.apes.fn.server.servicePlan.model.ServicePlan;
import com.apes.fn.server.servicePlan.repository.ServicePlanRepository;
import com.apes.fn.server.workOrder.model.MaintenanceOrder;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.plugin.soe.metadata.BusinessAttributeValue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * @Classname ReworkAppraisalService
 * @Description 返修鉴定单
 * @Date 2020/1/2 14:48
 * @Created by wsj
 */
@Service("fnReworkAppraisalService")
public class ReworkAppraisalService extends DomainService {
    @Autowired
    private ReworkAppraisalRepository reworkAppraisalRepository;
    @Autowired
    private ReworkAppraisalToSql reworkAppraisalToSql;

    public ReworkAppraisal save(SimpleRequest request) {
        //新增前判断是否该服务单号已经存在未完成的返修鉴定单
        ReworkAppraisal reworkAppraisal = request.getO(ReworkAppraisal.class);
        reworkAppraisal.setState("create");
        return  reworkAppraisalRepository.saveAndFlush(reworkAppraisal);
    }

    public void checkExists(ReworkAppraisal reworkAppraisal) {
        List<ReworkAppraisal> list = reworkAppraisalRepository.findAll(JpaDsl.toCriteriaByEq("source",reworkAppraisal.getSource()));
        if (list.size() >0) throw new RuntimeException("该服务方案单已经存在有返修鉴定单!!!");
    }
    public ReworkAppraisal update(SimpleRequest request) {
        ReworkAppraisal reworkAppraisal = request.getO(ReworkAppraisal.class);
        return  reworkAppraisalRepository.saveAndFlush(reworkAppraisal);
    }

    public String delete(SimpleRequest request) throws Exception {
        ReworkAppraisal rework = checkData(request);
        if (rework.getState() != null && !"create".equals(rework.getState())) throw new RuntimeException("返修鉴定单状态不为新增，不能删除!!");
        ReworkAppraisal reworkAppraisal = request.getO(ReworkAppraisal.class);
        BusinessAttributeValue reworkType = reworkAppraisal.getReworkType();
        //如果是内部返修则需要退回服务方案
        if ("B".equals(reworkType.getCode())) {
            returnServicePlan(reworkAppraisal);
        }
        reworkAppraisal.setDeleteUid(getPerson(request));//设置人员
        reworkAppraisal.setDeleteDate(new Date());
        reworkAppraisal.setState("delete");
        reworkAppraisalRepository.saveAndFlush(reworkAppraisal);
        return "删除成功！";
    }

    /**
     * 功能：审批返修鉴定单
     *
     * @param request
     * @return
     */
    public ReworkAppraisal approve(SimpleRequest request) {
        ReworkAppraisal appraisal = checkData(request);
        if (appraisal.getState() != null && !"create".equals(appraisal.getState())) throw new RuntimeException("返修鉴定单状态不为新增，不能审核!!!");  // 用于判断当前版本是否被修改
        ReworkAppraisal reworkAppraisal = request.getO(ReworkAppraisal.class);
        reworkAppraisal.setState("approve");
        reworkAppraisal.setApproveUid(request.getPerson());
        reworkAppraisal.setApproveDate(new Date());
        reworkAppraisal = reworkAppraisalRepository.saveAndFlush(reworkAppraisal);
        return  reworkAppraisal;
    }

    private ReworkAppraisal checkData(SimpleRequest request) {
        String id = request.get("id");
        long versions = (int) request.get("version"); // 获取当前请求的版本信息
        ReworkAppraisal reworkAppraisal = reworkAppraisalRepository.findOne(id);
        if (reworkAppraisal == null) throw new RuntimeException("返修鉴定单【" + id + "】在系统中不存在。");
        if (reworkAppraisal.getVersion() != versions) throw new RuntimeException("记录已更新或已删除，请重新提交！");
        return  reworkAppraisal;
    }


    /**
     * 功能：鉴定
     *
     * @param request
     * @return
     */
    public ReworkAppraisal appraisal(SimpleRequest request) throws Exception {
        ReworkAppraisal appraisal = checkData(request);
        if (appraisal.getState() != null && !"approve".equals(appraisal.getState())) throw new RuntimeException("返修鉴定单状态不为审核，不能鉴定!!!");
        ReworkAppraisal reworkAppraisal = request.getO(ReworkAppraisal.class);
        reworkAppraisal = computeAmountToPay(reworkAppraisal);
        reworkAppraisal.setState("appraisal");
        reworkAppraisal.setAppraisalUid(request.getPerson());
        reworkAppraisal.setAppraisalDate(new Date());
        reworkAppraisal = reworkAppraisalRepository.saveAndFlush(reworkAppraisal);
        return  reworkAppraisal;
    }

    // /**
    //  * 功能：分摊
    //  *
    //  * @param request
    //  * @return
    //  */
    // public ReworkAppraisal apportion(SimpleRequest request) throws Exception {
    //     ReworkAppraisal appraisal = checkData(request);
    //     if (appraisal.getState() != null && !"appraisal".equals(appraisal.getState())) throw new RuntimeException("返修鉴定单状态不为鉴定，不能分摊!!!");
    //     ReworkAppraisal reworkAppraisal = request.getO(ReworkAppraisal.class);
    //     if (reworkAppraisal.getPersonalToBear() > 0 ) computeAmount(reworkAppraisal);
    //     reworkAppraisal.setState("apportion");
    //     reworkAppraisal.setApportionUid(request.getPerson());
    //     reworkAppraisal.setApportionDate(new Date());
    //     reworkAppraisal = reworkAppraisalRepository.saveAndFlush(reworkAppraisal);
    //     return  reworkAppraisal;
    // }

    /**
     * 功能：分发
     *
     * @param request
     * @return
     */
    public ReworkAppraisal dispense(SimpleRequest request) {
        ReworkAppraisal appraisal = checkData(request);
        if (appraisal.getState() != null && !"appraisal".equals(appraisal.getState())) throw new RuntimeException("返修鉴定单状态不为鉴定，不能分发红包!!");
        ReworkAppraisal reworkAppraisal = request.getO(ReworkAppraisal.class);
        reworkAppraisal.setState("dispense");
        reworkAppraisal.setDispenseUid(request.getPerson());
        reworkAppraisal.setDispenseDate(new Date());
        reworkAppraisal = reworkAppraisalRepository.saveAndFlush(reworkAppraisal);
        return  reworkAppraisal;
    }

    /**
     * 功能：终止
     *
     * @param request
     * @return
     */
    public String repeal(SimpleRequest request) throws Exception {
        ReworkAppraisal appraisal = checkData(request);
        if (appraisal.getState() != null && !"approve".equals(appraisal.getState())) throw new RuntimeException("返修鉴定单状态不为审核，不能终止!!!");
        String reworkServePlan = appraisal.getReworkServePlan();
        List<ServicePlan> list = SpringManager.getBean(ServicePlanRepository.class).findAll(
                JpaDsl.toCriteriaByEq("id",reworkServePlan, "state", "delete","deleteDate",null)
        );
        if (list.size() != 0) throw new RuntimeException("该返修鉴定单生成新的服务方案单未删除，无法终止，服务单号：" + list.get(0).getId());
        ReworkAppraisal reworkAppraisal = request.getO(ReworkAppraisal.class);
        BusinessAttributeValue reworkType = reworkAppraisal.getReworkType();
        // //如果是内部返修则需要退回服务方案 todo
        // if ("B".equals(reworkType.getCode())) {
        //     returnServicePlan(reworkAppraisal);
        // }
        reworkAppraisal.setState("repeal");
        reworkAppraisal.setRepealUid(request.getPerson());
        reworkAppraisal.setRepealDate(new Date());
        reworkAppraisalRepository.saveAndFlush(reworkAppraisal);
        return  "终止成功";
    }

    /**
     * 退回服务方案
     * @param
     */
    private void returnServicePlan(ReworkAppraisal reworkAppraisal) throws Exception{
        ServicePlanRepository servicePlanRepository = SpringManager.getBean(ServicePlanRepository.class);
        ServicePlan servicePlan = servicePlanRepository.findOne(reworkAppraisal.getReworkServePlan());
        servicePlan.setState("return");
        servicePlanRepository.saveAndFlush(servicePlan);
    }

    /**
     * 计算赔付红包金额
     * @param
     */
    private ReworkAppraisal computeAmountToPay(ReworkAppraisal reworkAppraisal) throws Exception{
        reworkAppraisal.getReworkAppraisalItems().forEach(
                (item) -> {
                    if( item.getResponsibleParty() == null ||  item.getReworkReason() ==null ){
                        throw new RuntimeException("责任方以及返修原因不能为空!!!!");
                    }
                    if (item.getWarrantyQty() > 0 && item.getWarrantyAmount() > 0) {
                        item.setRedPacket(item.getWarrantyAmount()*0.05);
                    }
                }
        );
       return  reworkAppraisal;
    }

    // /**
    //  * 个人分配金额计算
    //  * @param
    //  */
    // private void computeAmount(ReworkAppraisal reworkAppraisal) throws Exception{
    //     Set<ReworkApportionCost> set =  reworkAppraisal.getReworkApportionCosts();
    //     if (set == null ) throw new RuntimeException ("分摊明细数据不允许为空!!!");
    //     //判断分摊金额是否与主表的上面的金额相等
    //     double personalToBear = reworkAppraisal.getPersonalToBear(); //主表金额
    //     double personalToBearItem = set.stream().mapToDouble(ReworkApportionCost::getApportion).sum(); //从表金额
    //     if (personalToBear != personalToBearItem) {
    //         throw new RuntimeException ("个人分配金额计算有误!!!");
    //     }
    // }
    /**
     * 功能：写入质保赔付单 更新服务单方案商品 以及发红包
     * @param
     */
    private void writeBackBill(ReworkAppraisal reworkAppraisal) throws Exception{
        // TODO 需要补全功能 生成红包, 以及生成质保赔付单
        JSONObject mainObject = new JSONObject();
        Set<ReworkAppraisalItem> set = reworkAppraisal.getReworkAppraisalItems();
        double redPacketTotal = 0;
        JSONArray array = new JSONArray();
        for (ReworkAppraisalItem item : set ) {
            if (item.getRedPacket() < 0) throw new RuntimeException("红包金额不能为负数，商品编码：" + item.getProduct());
            if (item.getRedPacket() > 0 &&  item.getWarrantyQty() == 0) throw new RuntimeException("红包对应的质保数量不能为零，商品编码：" + item.getProduct() );
            if( item.getRedPacket() > 0 ) {
                redPacketTotal += item.getRedPacket();
                array.add(item);
            }
        }
        array.forEach(
                item -> {
                    JSONObject param = new JSONObject();
                    JSONObject item1 = (JSONObject)item;
                    item1.put("servicePlan",reworkAppraisal.getSource());
                    reworkAppraisalToSql.updateReworkAppraisalItem(item1);
                    reworkAppraisalToSql.updateServicePlanItem(item1);
                }
        );
        mainObject.put("red_packet_total", redPacketTotal);
    }

    public JSONObject findMaintenanceOrder (SimpleRequest request) {
        JSONObject object = request.getJO();
        JSONObject param = object.getJSONObject("data");
        JSONArray array = param.getJSONArray("reworkAppraisalItems");
        array.forEach(
                item -> {
                    JSONObject obj = (JSONObject) item;
                    MaintenanceOrder order = null;
                    try {
                        order = reworkAppraisalRepository.findByServicePlanId(obj.getString("id"));
                    } catch (Exception e) {
                        throw new RuntimeException("查询服务工工单出现问题!!!");
                    }
                    if (order != null) {
                        if (order.getInnerDept() != null){
                            obj.put("constructionSide", order.getInnerDept().getName());
                        }else if (order.getToOutDate() != null) {
                            obj.put("constructionSide", "供应商");
                        }else {
                            obj.put("constructionSide", order.getBelongDept().getName());
                        }
                    }else {
                        obj.put("constructionSide", param.getJSONObject("belongDept").getString("name"));
                    }

                }
        );
        return param;
    }
}


